use std::any::Any;
use std::time::Duration;

use anyhow::Result;
use async_trait::async_trait;
use tracing::{info, debug, warn};

use protoactor_rs::actor::{Actor, ActorContext, ActorError, DefaultActorContext, Props};
use protoactor_rs::system::{self, ActorSystem};
use protoactor_rs::logging;

// 定义一个简单的测试actor
struct TestActor;

#[async_trait]
impl Actor for TestActor {
    type Context = DefaultActorContext;
    
    async fn receive(&self, ctx: &mut Self::Context, msg: Box<dyn Any + Send>) -> Result<(), ActorError> {
        // 使用 type_id 可以帮助我们识别消息类型
        debug!("TestActor received message of type: {:?}", msg.type_id());
        
        // 使用 downcast_ref 而不是 downcast 来避免消耗消息所有权
        if let Some(s) = msg.downcast_ref::<String>() {
            info!("TestActor received string message: {}", s);
            // 如果消息是"hello"，回复"world"
            if s.as_str() == "hello" {
                ctx.respond("world".to_string());
                debug!("Responding with 'world'");
            }
        } else if let Some(i) = msg.downcast_ref::<i32>() {
            info!("TestActor received integer message: {}", i);
        } else {
            warn!("TestActor received unknown message type");
        }
        
        Ok(())
    }
    
    async fn started(&self, _ctx: &mut Self::Context) -> Result<(), ActorError> {
        info!("TestActor started");
        Ok(())
    }
    
    async fn stopping(&self, _ctx: &mut Self::Context) -> Result<(), ActorError> {
        info!("TestActor stopping");
        Ok(())
    }
}

#[tokio::main]
async fn main() -> Result<()> {
    // 初始化日志系统
    logging::init_global_logger(
        Some(tracing::Level::DEBUG),
        Some("simple_test=info"),
    ).map_err(|e| anyhow::anyhow!("日志初始化失败: {}", e))?;
    
    // 初始化全局 ActorSystem 实例
    let system = system::get_or_create_system();
    info!("Global ActorSystem initialized");
    
    // 创建actor props
    let props = Props::from_producer(|| TestActor);
    
    // 生成actor
    let actor_pid = system.spawn::<TestActor>(props).await.unwrap();
    
    info!("Actor spawned with PID: {}", actor_pid);
    
    // 发送一个字符串消息
    actor_pid.send("hello".to_string()).await?;
    
    // 等待一会儿让消息被处理
    tokio::time::sleep(Duration::from_millis(100)).await;
    
    // 发送一个整数消息
    actor_pid.send(42).await?;
    
    // 等待一会儿让消息被处理
    tokio::time::sleep(Duration::from_millis(100)).await;
    
    // 停止actor
    system.stop(&actor_pid).await?;
    
    // 等待一会儿让actor停止
    tokio::time::sleep(Duration::from_millis(100)).await;
    
    info!("Test completed successfully");
    
    Ok(())
} 